from flask import Flask, render_template,request,redirect,url_for
from sqlalchemy import text  # 新增导入
from flask_login import  UserMixin, current_user, login_user,login_required, logout_user
from extensions import db, login_manager,i_maotai_rob
from flask_apscheduler import APScheduler
from datetime import datetime
from utils.utils import *


# 指定模板目录
app = Flask(__name__, template_folder='web/templates')
app.secret_key = '12345678'

# 初始化调度器
scheduler = APScheduler()
scheduler.init_app(app)
scheduler.start()


# MySQL 配置
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:soloman@123.57.9.213:3306/imaotai'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
    'pool_size': 10,
    'pool_recycle': 300,
    'pool_pre_ping': True
}

# 初始化扩展
db.init_app(app)
login_manager.init_app(app)
login_manager.login_view = 'view.login'
get_db_config(app)



# 注册蓝图
from web.routes import web_bp
app.register_blueprint(web_bp, url_prefix='')
from api.routes import api_bp
app.register_blueprint(api_bp, url_prefix='/api')






# 每天6点执行
@scheduler.task('cron', id='morning_job', hour=6, minute=0, timezone='Asia/Shanghai')
def my_job():
    print("定时任务执行中...")
    # 定时获取可预约的商品列表
    with app.app_context():  # 手动创建应用上下文
        product = i_maotai_rob.get_item_info()
        for i in product['itemList']:
            formatted_date =  datetime.now().strftime("%Y-%m-%d") 
            sql = f"""
                INSERT INTO products 
                    (SessionId, product_id,product_name,created_date) 
                VALUES ('{product["sessionId"]}','{i["itemCode"]}','{i["title"]}','{formatted_date}');
            """
            db.session.execute(text(sql))
            db.session.commit()

        # 获取最新的 SESSIONID 并更新数据配置
        SESSIONID = product['sessionId']
        sql = f"""
                UPDATE 
                    config
                SET 
                    Value = {SESSIONID}
                WHERE 
                    Name = 'SESSIONID';

            """
        db.session.execute(text(sql))
        db.session.commit()

        # 获取最新的版本号 并更新数据配置
        mt_version = i_maotai_rob.get_mt_version()
        sql = f"""
                UPDATE 
                    config
                SET 
                    Value = '{mt_version}'
                WHERE 
                    Name = 'MT_VERSION';

            """
        db.session.execute(text(sql))
        db.session.commit()

        # 更新配置
        get_db_config(app)


# 每天9点01执行
@scheduler.task('cron',id='imaotai_job', hour=9,minute=1,timezone='Asia/Shanghai')
def my_imaotai():
    print("定时任务执行中...")
    with app.app_context():
        sql = f"""
                SELECT 
                    * 
                FROM 
                    imaotai_user
                WHERE 
                    status=1
            """
        result = db.session.execute(text(sql))
        imaotai_user = [dict(row._mapping) for row in result]
        for i in imaotai_user:
            users_id = i['users_id']
            imaotai_user_id = i['imaotai_user_id']
            token = i['token']
            deviceId = i['device_id']
            verifyStatus = i['verifyStatus']
            if verifyStatus == 0:
                save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"用户未进行实名认证,退出预约,请尽快完成实名认证")
            else:
                # 获取当前省份当前地区的商店信息
                shop_info = i_maotai_rob.get_shop_info(i['province_name'], i['city_name'])
                products = i['products'].split(",")
                product_info = []

                for j in products:
                    # 获取的是当前省份所有商铺里所有商品可预约的数据
                    i_maotai_rob.get_shop_by_product_id(i['province_name'], j,product_info)

                # 将当前省份当前地区的商店信息 与 所有商铺里所有商品可预约的数据 进行整合处理
                for shop in shop_info:
                    data = []
                    for product in product_info:
                        if shop['shopId'] == product['shopId']:
                            data.append({'inventory':product['inventory'],'itemId':product['itemId']})
                    shop['province'] = data

                    # 计算距离
                    distance = i_maotai_rob.haversine(float(i['lat']), float(i['lng']), float(shop["lat"]),float(shop["lng"]))
                    shop['distance'] = distance

                # 开始准备预约商品
                # 判断用户设计的预约模式
                if i['appointmentMode'] == "NEAREST":

                    # 「选择-商店信息」
                    save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"「商铺模式-NEAREST」 距离最近")
            
                    # 按照距离近到远排序
                    shop_info.sort(key=lambda x: x["distance"])

                    SHOP_NAME = shop_info[0]['name']
                    SHOP_ID = shop_info[0]['shopId']
                    SHOP_FULLADDRESS = shop_info[0]['fullAddress']
                    SHOP_LAT = shop_info[0]['lat']
                    SHOP_LNG = shop_info[0]['lng']
                    SHOP_PROVINCE = shop_info[0]['province']
                    SHOP_DISTANCE = shop_info[0]['distance']
                    
                    # 进行商品预约
                    for province in SHOP_PROVINCE:
                        save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"「开始预约」商品ID:{province['itemId']},店铺名称：{SHOP_NAME},店铺ID: {SHOP_ID},地址: {SHOP_FULLADDRESS},纬度: {SHOP_LAT},维度: {SHOP_LNG},距离：{SHOP_DISTANCE} 公里")
                        # 预约商品
                        product_results = i_maotai_rob.reserve_product(
                                                                        itemId=province['itemId'],
                                                                        shopId=SHOP_ID,
                                                                        imaotai_user_id=imaotai_user_id,
                                                                        token=token,
                                                                        deviceId=deviceId,
                                                                        lat=SHOP_LAT,
                                                                        lng=SHOP_LNG
                                                                    )
                        save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"「预约结果」{product_results}")

                elif i['appointmentMode'] == "INVENTORY":
                    save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"「商铺模式-INVENTORY」 库存最多")
                    max_shop_info = i_maotai_rob.get_max_inventory_shops(shop_info)
                    for i in max_shop_info:

                        SHOP_NAME = i['name']
                        SHOP_ID = i['shopId']
                        SHOP_FULLADDRESS = i['fullAddress']
                        SHOP_LAT = i['lat']
                        SHOP_LNG = i['lng']
                        SHOP_DISTANCE = i['distance']
                        SHOP_PROVINCE = i['itemId']

                        save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"「开始预约」商品ID:{SHOP_PROVINCE},店铺名称：{SHOP_NAME},店铺ID: {SHOP_ID},地址: {SHOP_FULLADDRESS},纬度: {SHOP_LAT},维度: {SHOP_LNG},距离：{SHOP_DISTANCE} 公里")
                        # 预约商品
                        product_results = i_maotai_rob.reserve_product(
                                                                        itemId=SHOP_PROVINCE,
                                                                        shopId=SHOP_ID,
                                                                        imaotai_user_id=imaotai_user_id,
                                                                        token=token,
                                                                        deviceId=deviceId,
                                                                        lat=i['lat'],
                                                                        lng=i['lng']
                                                                    )
                        save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"「预约结果」{product_results}")



#申购结果获取 晚上18点01执行
@scheduler.task('cron', id='imaotai_result_job', hour=18,minute=1,timezone='Asia/Shanghai')
def my_imaotai_result():
    with app.app_context():
        sql = f"""
                SELECT 
                    * 
                FROM 
                    imaotai_user
                WHERE 
                    status=1
                AND 
                    verifyStatus = 1
            """
        result = db.session.execute(text(sql))
        imaotai_user = [dict(row._mapping) for row in result]
        for i in imaotai_user:
            formatted_date =  datetime.now().strftime("%Y-%m-%d") 
            i_maotai_rob_result = i_maotai_rob.check_reservation_result(i['token'],i['device_id'])
            for j in i_maotai_rob_result:
                sql = f"""
                        INSERT INTO imaotai_result 
                            (users_id,imaotai_user_id,imaotai_user_name,product_id,product_name,message,created_date) 
                        VALUES 
                            ({i["users_id"]}, {i["imaotai_user_id"]},'{i["imaotai_user_name"]}',{j["item_id"]},'{j["item_name"]}','{j["status_text"]}','{formatted_date}');
                    """
                
                db.session.execute(text(sql))
                db.session.commit()

# 判断 登录是否快过期  进行邮箱发送提醒 每天早上8点30执行 
@scheduler.task('cron',id='token_expire_job',hour=8,minute=30,timezone='Asia/Shanghai')
def my_token_expire():
    with app.app_context():
        sql = f"""
                SELECT
                    users_id,
                    imaotai_user_id,
                    imaotai_user_name,
                    token_expire_time,
                    email
                FROM
                    imaotai_user
                WHERE
                    status=1
                AND
                    verifyStatus = 1
            """
        result = db.session.execute(text(sql))
        imaotai_user = [dict(row._mapping) for row in result]

        # 获取当前时间
        current_time = datetime.now()

        for i in imaotai_user:
            imaotai_user_id = i['imaotai_user_id']
            users_id = i['users_id']
            token_expire_time = i['token_expire_time']
            email = i['email']
            imaotai_user_name = i['imaotai_user_name']

            # 判断token是否已过期或剩余时间小于6小时
            if token_expire_time:
                # 计算时间差
                time_diff = token_expire_time - current_time

                # 如果token已过期 或 剩余时间小于6小时，则发送提醒邮件
                if time_diff.total_seconds() <= 6 * 3600:
                    # 发送邮件提醒
                    send_email_reminder(
                        email=email,
                        username=imaotai_user_name,
                        expire_time=token_expire_time
                    )
                    save_imaotai_log(imaotai_user_id=imaotai_user_id,users_id=users_id,message=f"「邮件提醒」已向 {email} 发送token过期提醒邮件")



if __name__ == '__main__':
    # app.run(host='0.0.0.0',port=5002,debug=True)
    app.run(host='0.0.0.0',port=5002)